/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import java.beans.PropertyDescriptor;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;

/**
 * {@link BeanPostProcessor}的子接口，添加实例化前和实例化前（显式属性设置和自动装配之前）的回调方法。<br/>
 * Subinterface of {@link BeanPostProcessor} that adds a before-instantiation
 * callback, and a callback after instantiation but before explicit properties
 * are set or autowiring occurs.
 * 
 * <p>
 * 典型用来抑制指定目标bean的默认初始化，例如对特殊的目标源（pooling targets,lazily initializing
 * targets等）创建代理，或者实现附加的注入策略，例如field注入等。<br/>
 * Typically used to suppress default instantiation for specific target beans,
 * for example to create proxies with special TargetSources (pooling targets,
 * lazily initializing targets, etc), or to implement additional injection
 * strategies such as field injection.
 * 
 * <p>
 * <b>注意：</b>这个接口是特殊目的的接口，主要在框架内部使用。推荐尽量实现{@link BeanPostProcessor}，或者从
 * {@link InstantiationAwareBeanPostProcessorAdapter}获取以屏蔽从这个接口的扩展。<br/>
 * <b>NOTE:</b> This interface is a special purpose interface, mainly for
 * internal use within the framework. It is recommended to implement the plain
 * {@link BeanPostProcessor} interface as far as possible, or to derive from
 * {@link InstantiationAwareBeanPostProcessorAdapter} in order to be shielded
 * from extensions to this interface.
 * 
 * @author Juergen Hoeller
 * @author Rod Johnson
 * @since 1.2
 * @see org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#setCustomTargetSourceCreators
 * @see org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator
 */
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	/**
	 * #Comment#:在使用getBean(beanName)方法向容器请求一个bean的时候，如果容器注册了这个接口，则将调用此方法。
	 * <p>
	 * 在目标bean获得初始化之前执行这个BeanPostProcessor。返回的bean对象可能是一个目标bean的代理，
	 * 用来有效抑制目标bean的默认初始化。<br/>
	 * Apply this BeanPostProcessor <i>before the target bean gets
	 * instantiated</i>. The returned bean object may be a proxy to use instead
	 * of the target bean, effectively suppressing default instantiation of the
	 * target bean.
	 * <p>
	 * If a non-null object is returned by this method, the bean creation
	 * process will be short-circuited. The only further processing applied is
	 * the {@link #postProcessAfterInitialization} callback from the configured
	 * {@link BeanPostProcessor BeanPostProcessors}.
	 * <p>
	 * This callback will only be applied to bean definitions with a bean class.
	 * In particular, it will not be applied to beans with a "factory-method".
	 * <p>
	 * Post-processors may implement the extended
	 * {@link SmartInstantiationAwareBeanPostProcessor} interface in order to
	 * predict the type of the bean object that they are going to return here.
	 * 
	 * @param beanClass
	 *            the class of the bean to be instantiated
	 * @param beanName
	 *            the name of the bean
	 * @return the bean object to expose instead of a default instance of the
	 *         target bean, or <code>null</code> to proceed with default
	 *         instantiation
	 * @throws org.springframework.beans.BeansException
	 *             in case of errors
	 * @see org.springframework.beans.factory.support.AbstractBeanDefinition#hasBeanClass
	 * @see org.springframework.beans.factory.support.AbstractBeanDefinition#getFactoryMethodName
	 */
	Object postProcessBeforeInstantiation(Class beanClass, String beanName)
			throws BeansException;

	/**
	 * #Comment#:在使用getBean(beanName)方法向容器请求一个bean,在实例化Bean之后，如果容器注册了这个接口，
	 * 则将调用此方法。
	 * <p>
	 * Perform operations after the bean has been instantiated, via a
	 * constructor or factory method, but before Spring property population
	 * (from explicit properties or autowiring) occurs.
	 * 
	 * @param bean
	 *            the bean instance created, but whose properties have not yet
	 *            been set
	 * @param beanName
	 *            the name of the bean
	 * @return <code>true</code> if properties should be set on the bean;
	 *         <code>false</code> if property population should be skipped.
	 *         Normal implementations should return <code>true</code>. Returning
	 *         <code>false</code> will also prevent any subsequent
	 *         InstantiationAwareBeanPostProcessor instances being invoked on
	 *         this bean instance.
	 * @throws org.springframework.beans.BeansException
	 *             in case of errors
	 */
	boolean postProcessAfterInstantiation(Object bean, String beanName)
			throws BeansException;

	/**
	 * #Comment#:如果bean设置了property属性，容器将在设置bean的每个属性之前，调用这个方法。
	 * <p>
	 * Post-process the given property values before the factory applies them to
	 * the given bean. Allows for checking whether all dependencies have been
	 * satisfied, for example based on a "Required" annotation on bean property
	 * setters.
	 * <p>
	 * Also allows for replacing the property values to apply, typically through
	 * creating a new MutablePropertyValues instance based on the original
	 * PropertyValues, adding or removing specific values.
	 * 
	 * @param pvs
	 *            the property values that the factory is about to apply (never
	 *            <code>null</code>)
	 * @param pds
	 *            the relevant property descriptors for the target bean (with
	 *            ignored dependency types - which the factory handles
	 *            specifically - already filtered out)
	 * @param bean
	 *            the bean instance created, but whose properties have not yet
	 *            been set
	 * @param beanName
	 *            the name of the bean
	 * @return the actual property values to apply to to the given bean (can be
	 *         the passed-in PropertyValues instance), or <code>null</code> to
	 *         skip property population
	 * @throws org.springframework.beans.BeansException
	 *             in case of errors
	 * @see org.springframework.beans.MutablePropertyValues
	 */
	PropertyValues postProcessPropertyValues(PropertyValues pvs,
			PropertyDescriptor[] pds, Object bean, String beanName)
			throws BeansException;

}
